﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FIFP.Common;
using System.Collections.ObjectModel;
using Telerik.Windows.Controls.Charting;
using System.Collections.Generic;
using Telerik.Windows.Controls;
using FIFP.DashBoard.Helper;
using FIFP.DashBoard.Model;
using System.ComponentModel.DataAnnotations;
using FIFP.DashBoard.Converters;
using System.ComponentModel;
using System.Collections;
using System.Linq.Expressions;
using FIFP.DashBoard.RelationalDataService;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Linq;
using FIFP.DashBoard.Views;
using System.ServiceModel;

namespace FIFP.DashBoard.ViewModel
{
    public class ChartViewModel : ViewModelCore, INotifyPropertyChanged, INotifyDataErrorInfo
    {
        #region Variables
        RadChart scenarioChart;
        private DateTime startDate = new DateTime(DateTime.Now.Year, 1, 1);
        private DateTime endDate = new DateTime(DateTime.Now.Year, 12, 31);
        private readonly ICollection<ValidationResult> _validationResults;
        private List<string> selectedCapacityTypes = new List<string>();
        private List<string> selectedScenarioIds = new List<string>();
        private string selectedCapacityType = string.Empty;
        private string selectedScenarioId = string.Empty;
        #endregion

        #region Properties
        private List<ScenarioCapacity> userScenarioCapacityDataList = new List<ScenarioCapacity>();
        public List<ScenarioCapacity> UserScenarioCapacityDataList
        {
            get { return userScenarioCapacityDataList; }
            set { SetPropertyValue(() => UserScenarioCapacityDataList, value, val => userScenarioCapacityDataList = val); }
        }

        private List<ScenarioCapacity> eCPlanCapacityDataList = new List<ScenarioCapacity>();
        public List<ScenarioCapacity> ECPlanCapacityDataList
        {
            get { return eCPlanCapacityDataList; }
            set { SetPropertyValue(() => ECPlanCapacityDataList, value, val => eCPlanCapacityDataList = val); }
        }


        private Scenario selectedScenario;
        public Scenario SelectedScenario
        {
            get { return selectedScenario; }
            set
            {
                if (value == null)
                    return;
                selectedScenario = value;
                NotifyPropertyChanged(() => SelectedScenario);
            }
            //set { SetPropertyValue(() => SelectedScenario, value, val => selectedScenario = val); }
        }

        private Scenario selectedOtherScenario = new Scenario();
        public Scenario SelectedOtherScenario
        {
            get { return selectedOtherScenario; }
            set
            {
                if (value == null)
                    return;
                selectedOtherScenario = value;
                NotifyPropertyChanged(() => SelectedOtherScenario);
            }
            //set { SetPropertyValue(() => SelectedOtherScenario, value, val => selectedOtherScenario = val); }
        }
        
        private List<ScenarioCapacity> scenarioECList = new List<ScenarioCapacity>();
        public List<ScenarioCapacity> ScenarioECList
        {
            get { return scenarioECList; }
            set { SetPropertyValue(() => ScenarioECList, value, val => scenarioECList = val); }
        }



        private Dictionary<string, DataSeries> dataSeriesCapacityList = new Dictionary<string, DataSeries>();
        public Dictionary<string, DataSeries> DataSeriesCapacityList
        {
            get { return dataSeriesCapacityList; }
            set { SetPropertyValue(() => DataSeriesCapacityList, value, val => dataSeriesCapacityList = val); }
        }

        private ObservableCollection<Scenario> userScenarioList = new ObservableCollection<Scenario>();
        public ObservableCollection<Scenario> UserScenarioList
        {
            get { return userScenarioList; }
            set { SetPropertyValue(() => UserScenarioList, value, val => userScenarioList = val); }
        }

        private List<Scenario> othersScenarioList = new List<Scenario>();
        public List<Scenario> OthersScenarioList
        {
            get { return othersScenarioList; }
            set { SetPropertyValue(() => OthersScenarioList, value, val => othersScenarioList = val); }
        }

        private ObservableCollection<Scenario> currentUserScenarioList = new ObservableCollection<Scenario>();
        public ObservableCollection<Scenario> CurrentUserScenarioList
        {
            get { return currentUserScenarioList; }
            set
            {
                if (currentUserScenarioList != value)
                {
                    currentUserScenarioList = value;
                    NotifyPropertyChanged(() => CurrentUserScenarioList);
                }
            }
            //set { SetPropertyValue(() => SelectedScenarioList, value, val => selectedScenarioList = val); }
        }

        private ObservableCollection<Scenario> otherUsersScenarioList = new ObservableCollection<Scenario>();
        public ObservableCollection<Scenario> OtherUsersScenarioList
        {
            get { return otherUsersScenarioList; }
            set
            {
                if (otherUsersScenarioList != value)
                {
                    otherUsersScenarioList = value;
                    NotifyPropertyChanged(() => OtherUsersScenarioList);
                }
            }
            //set { SetPropertyValue(() => SelectedScenarioList, value, val => selectedScenarioList = val); }
        }


        private List<CapacityType> capacityDataList = new List<CapacityType>();
        public List<CapacityType> CapacityDataList
        {
            get { return capacityDataList; }
            set { SetPropertyValue(() => CapacityDataList, value, val => capacityDataList = val); }
        }

        private ObservableCollection<CapacityType> filteredCapacityDataList = new ObservableCollection<CapacityType>();
        public ObservableCollection<CapacityType> FilteredCapacityDataList
        {
            get { return filteredCapacityDataList; }
            set { SetPropertyValue(() => FilteredCapacityDataList, value, val => filteredCapacityDataList = val); }
        }

        [Display(Name = FIFPConstants.DISPLAY_STARTDATE)]
        [CustomValidation(typeof(ErrorValidation), FIFPConstants.VALIDATE_SCENARIO_STARTDATE)]
        public DateTime StartDate
        {
            get { return startDate; }
            set
            {
                if (startDate != value)
                {
                    startDate = value;
                    NotifyPropertyChanged(() => StartDate);
                    NotifyPropertyChanged(() => this.EndDate);
                }
            }
        }

        [Display(Name = FIFPConstants.DISPLAY_ENDDATE)]
        [CustomValidation(typeof(ErrorValidation), FIFPConstants.VALIDATE_SCENARIO_ENDDATE)]
        public DateTime EndDate
        {
            get { return endDate; }
            set
            {
                if (endDate != value)
                {
                    endDate = value;
                    NotifyPropertyChanged(() => this.EndDate);
                    NotifyPropertyChanged(() => StartDate);
                }
            }
        }

        private Visibility eCPlanVisibility = Visibility.Collapsed;
        public Visibility ECPlanVisibility
        {
            get { return eCPlanVisibility; }
            set { SetPropertyValue(() => ECPlanVisibility, value, val => eCPlanVisibility = val); }
        }

        private double _ScenarioCapacityMaxValue = 400;
        public double ScenarioCapacityMaxValue
        {
            get { return _ScenarioCapacityMaxValue; }
            set { SetPropertyValue(() => ScenarioCapacityMaxValue, value, val => _ScenarioCapacityMaxValue = val); }
        }

        private List<int> noCalculatedScenarioList = new List<int>();
        public List<int> NoCalculatedScenarioList
        {
            get { return noCalculatedScenarioList; }
            set { SetPropertyValue(() => NoCalculatedScenarioList, value, val => noCalculatedScenarioList = val); }
        }

        private Visibility currentUserScenarioVisibility = Visibility.Collapsed;
        public Visibility CurrentUserScenarioVisibility
        {
            get { return currentUserScenarioVisibility; }
            set { SetPropertyValue(() => CurrentUserScenarioVisibility, value, val => currentUserScenarioVisibility = val); }
        }

        private Visibility otherUserScenarioVisibility = Visibility.Collapsed;
        public Visibility OtherUserScenarioVisibility
        {
            get { return otherUserScenarioVisibility; }
            set { SetPropertyValue(() => OtherUserScenarioVisibility, value, val => otherUserScenarioVisibility = val); }
        }

        #endregion

        #region Commands
        private ICommand _RadChartLoadedCommand;
        public ICommand RadChartLoadedCommand
        {
            get
            {
                return _RadChartLoadedCommand ??
                        (_RadChartLoadedCommand = new RelayCommand<RadChart>(LoadRadChart));
            }
        }

        private ICommand _ScenarioCommand;
        public ICommand ScenarioCommand
        {
            get
            {
                return _ScenarioCommand ??
                        (_ScenarioCommand = new RelayCommand<CheckBox>(ScenarioCheckedEvent));
            }
        }

        private ICommand _CapacityCommand;
        public ICommand CapacityCommand
        {
            get
            {
                return _CapacityCommand ??
                        (_CapacityCommand = new RelayCommand<CheckBox>(CapacityCheckedEvent));
            }
        }

        private ICommand _SelectedStartDateChangedCommand;
        public ICommand SelectedStartDateChangedCommand
        {
            get
            {
                return _SelectedStartDateChangedCommand ??
                        (_SelectedStartDateChangedCommand = new RelayCommand<DatePicker>(StartDate_SelectedDateChanged));
            }
        }

        private ICommand _StartDateLoadedCommand;
        public ICommand StartDateLoadedCommand
        {
            get
            {
                return _StartDateLoadedCommand ??
                        (_StartDateLoadedCommand = new RelayCommand<DatePicker>(LoadStartDate));
            }
        }
        private ICommand _EndDateLoadedCommand;
        public ICommand EndDateLoadedCommand
        {
            get
            {
                return _EndDateLoadedCommand ??
                        (_EndDateLoadedCommand = new RelayCommand<DatePicker>(LoadEndDate));
            }
        }

        private ICommand _ReloadScenarioEvent;
        public ICommand ReloadScenarioEvent
        {
            get
            {
                return _ReloadScenarioEvent ??
                        (_ReloadScenarioEvent = new RelayCommand<Button>(ReloadScenario));
            }
        }

        private ICommand _ScenarioSelectionCommand;
        public ICommand ScenarioSelectionCommand
        {
            get
            {
                return _ScenarioSelectionCommand ??
                        (_ScenarioSelectionCommand = new RelayCommand<ComboBox>(BuildScenarioGrid));
            }
        }

        private ICommand _OtherScenarioSelectionCommand;
        public ICommand OtherScenarioSelectionCommand
        {
            get
            {
                return _OtherScenarioSelectionCommand ??
                        (_OtherScenarioSelectionCommand = new RelayCommand<ComboBox>(BuildOtherScenarioGrid));
            }
        }

        #endregion

        #region Constructor
        public ChartViewModel()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                _validationResults = new List<ValidationResult>();
                ServiceLocator.Get<MainPageVM>().OnScenarioClick += new EventHandler(ChartViewModel_OnScenarioClick);
                
                GetScenariosFromDB();
                BuildCapacityDataList();
                GetUserScenarioData();
                
            }
        }

        #region Reload Scenarios
        private void ReloadScenario(Button btnRefresh)
        {
            ServiceLocator.Get<MainPageVM>().IsLoading = true;
            GetUserScenarioData();
        }
        #endregion

        #region Reset Filter
        public void ResetScenarioFilterData()
        {
            selectedCapacityTypes = new List<string>();
            selectedScenarioIds = new List<string>();
            selectedCapacityType = string.Empty;
            selectedScenarioId = string.Empty;

            if (scenarioChart != null && scenarioChart.DefaultView.ChartArea.DataSeries != null && scenarioChart.DefaultView.ChartArea.DataSeries.Count > 0)
                scenarioChart.DefaultView.ChartArea.DataSeries.RemoveAll();
            if (DataSeriesCapacityList != null && DataSeriesCapacityList.Count > 0)
                DataSeriesCapacityList = new Dictionary<string, DataSeries>();
            List<CapacityType> fList = new List<CapacityType>();
            if (CapacityDataList != null && CapacityDataList.Count > 0 && CapacityDataList.Where(s => s.ItemChecked == true).Count() > 0)
            {
                fList = new List<CapacityType>(CapacityDataList);
                fList.ForEach(s => { s.ItemChecked = false; });
                CapacityDataList = new List<CapacityType>(fList);
                FilteredCapacityDataList = new ObservableCollection<CapacityType>(CapacityDataList);
            }

            List<Scenario> sList = new List<Scenario>();
            if (CurrentUserScenarioList != null && CurrentUserScenarioList.Count > 0 && CurrentUserScenarioList.Where(s => s.ItemChecked == true).Count() > 0)
            {
                sList = new List<Scenario>(CurrentUserScenarioList);
                sList.ForEach(s => { s.ItemChecked = false; });
                CurrentUserScenarioList = new ObservableCollection<Scenario>(sList);
            }

            if (OtherUsersScenarioList != null && OtherUsersScenarioList.Count > 0 && OtherUsersScenarioList.Where(s => s.ItemChecked == true).Count() > 0)
            {
                sList = new List<Scenario>(OtherUsersScenarioList);
                sList.ForEach(s => { s.ItemChecked = false; });
                OtherUsersScenarioList = new ObservableCollection<Scenario>(sList);
            }
        }
        #endregion

        private void BuildCapacityDataList()
        {
            CapacityDataList = new List<CapacityType>() 
            {
                new CapacityType(){ CapacityName ="Reservoir Capacity", CapacityTypeName="RC",ItemChecked=false},
                new CapacityType(){ CapacityName ="100% Effiecient Capacity", CapacityTypeName="MC",ItemChecked=false},
                new CapacityType(){ CapacityName ="Available Oil", CapacityTypeName="OC",ItemChecked=false},
            };
            //if (ServiceLocator.Get<ImportVM>().BECScanrio)
            //{
            //    CapacityDataList.Add(new CapacityType() { CapacityName = "EC Plan " + DateTime.Now.Year, CapacityTypeName = "EC", ItemChecked = false });
            //}
            FilteredCapacityDataList = new ObservableCollection<CapacityType>(CapacityDataList);
        }

        private void BuildOtherScenarioGrid(ComboBox cmbOtherScenario)
        {
            if (SelectedOtherScenario != null && SelectedOtherScenario.ScenarioName != FIFPConstants.SELECT_SCENARIO)
            {
                List<Scenario> scenarioList = new List<Scenario>(OtherUsersScenarioList.OrderBy(s => s.ScenarioName));
                if (scenarioList != null && !scenarioList.Contains(SelectedOtherScenario))
                {
                    OtherUsersScenarioList.Add(SelectedOtherScenario);
                }
            }

            if (OtherUsersScenarioList != null && OtherUsersScenarioList.Count > 0)
                OtherUserScenarioVisibility = Visibility.Visible;
            else
                OtherUserScenarioVisibility = Visibility.Collapsed;
        }

        private void BuildScenarioGrid(ComboBox cmbScenario)
        {
            if (SelectedScenario != null && SelectedScenario.ScenarioName != FIFPConstants.SELECT_SCENARIO)
            {
                if (SelectedScenario.PlanType == "USC" && SelectedScenario.UserName == App.LoginUserName)
                {
                    List<Scenario> scenarioList = new List<Scenario>(CurrentUserScenarioList.OrderBy(s => s.ScenarioName));
                    if (scenarioList != null && !scenarioList.Contains(SelectedScenario))
                    {
                        CurrentUserScenarioList.Add(SelectedScenario);
                    }
                }                
            }
            if (CurrentUserScenarioList != null && CurrentUserScenarioList.Count > 0)
                CurrentUserScenarioVisibility = Visibility.Visible;
            else
                CurrentUserScenarioVisibility = Visibility.Collapsed;
        }

        void ChartViewModel_OnScenarioClick(object sender, EventArgs e)
        {
            DateTime startDate = ServiceLocator.Get<FilterVM>().StartDate;
            DateTime endDate = ServiceLocator.Get<FilterVM>().EndDate;
            DateTime actualStartDate = new DateTime(startDate.Year, startDate.Month, 1);
            DateTime actualEndDate = new DateTime(endDate.Year, endDate.Month, DateTime.DaysInMonth(endDate.Year, endDate.Month));

            StartDate = actualStartDate;
            endDate = actualEndDate;

            if (ServiceLocator.Get<ImportVM>().BReloadScenario)
            {
                //If selected scenario has not yet been calculated, 
                ServiceLocator.Get<ImportVM>().BReloadScenario = false;
                ServiceLocator.Get<MainPageVM>().IsLoading = true;
                GetScenariosFromDB();
                GetUserScenarioData();
            }
        }


        private void GetScenariosFromDB()
        {
            RelationalDataServiceClient queryClient = new RelationalDataServiceClient(FIFPServiceHostUtil.GetQueryBasicHttpBinding(), FIFPServiceHostUtil.GetQueryEndpointAddress());
            queryClient.QueryForDataAsync(FIFPConstants.DATASOURCE_ID, FIFPConstants.SELECT_ALL_SCENARIOS_QUERY_ID, null, "DBScenario");
            queryClient.QueryForDataCompleted += new EventHandler<QueryForDataCompletedEventArgs>(ChartVM_QueryForScenarioDataCompleted);
        }

        private void ChartVM_QueryForScenarioDataCompleted(object sender, QueryForDataCompletedEventArgs e)
        {
            ServiceLocator.Get<MainPageVM>().IsLoading = false;
            if (e.Result != null && e.Error == null)
            {
                if (e.UserState.ToString() == "DBScenario")
                {
                    try
                    {
                        StringReader reader = new StringReader(e.Result.Any1.ToString());
                        XmlReader xmlR = XmlReader.Create(reader);

                        XDocument doc = XDocument.Load(xmlR);
                        if (doc != null)
                        {
                            List<Scenario> scenarioList = (from item in doc.Descendants("Query")
                                                           select new Scenario
                                                           {
                                                               ScenarioId = item.Element("scenarioId") != null ? Convert.ToInt32(item.Element("scenarioId").Value) : 0,
                                                               ScenarioName = item.Element("scenarioName") != null ? Convert.ToString(item.Element("scenarioName").Value) : string.Empty,
                                                               ScenarioDescription = item.Element("scenarioName") != null ? Convert.ToString(item.Element("scenarioName").Value) : string.Empty,
                                                               UserName = item.Element("userName") != null ? Convert.ToString(item.Element("userName").Value) : string.Empty,
                                                               PlanType = item.Element("planType") != null ? Convert.ToString(item.Element("planType").Value) : string.Empty
                                                           }).ToList<Scenario>();
                            BuildScenarioCombo(scenarioList);
                        }
                    }
                    catch (Exception ex)
                    { }
                }
            }
            else
            {
                ServiceLocator.Get<MainPageVM>().IsLoading = false;
                MessageBox.Show("Database connection error while getting scenario information.");
            }
        }


        public void BuildScenarioCombo(List<Scenario> dbScenarioList)
        {
            List<Scenario> scenarioList = new List<Scenario>();
            scenarioList.Add(new Scenario() { ScenarioName = FIFPConstants.SELECT_SCENARIO, ScenarioId = 0, ScenarioDescription = "select scenario" });
            scenarioList.AddRange(dbScenarioList.Where(c => c.PlanType == "USC" && c.UserName == App.LoginUserName).OrderBy(s => s.ScenarioName));
            UserScenarioList = new ObservableCollection<Scenario>( scenarioList);
            

            scenarioList = new List<Scenario>();
            scenarioList.Add(new Scenario() { ScenarioName = FIFPConstants.SELECT_SCENARIO, ScenarioId = 0, ScenarioDescription = "select scenario" });
            scenarioList.AddRange(dbScenarioList.Where(c => c.UserName != App.LoginUserName).OrderBy(s => s.ScenarioName));
            OthersScenarioList = scenarioList;

            SelectedScenario = UserScenarioList[0];
            SelectedOtherScenario = OthersScenarioList[0];

        }

        private void BuildOthersScenarioCombo()
        {
            List<Scenario> scenarioList = new List<Scenario>();
            scenarioList.Add(new Scenario() { ScenarioName = FIFPConstants.SELECT_SCENARIO, ScenarioId = 0, ScenarioDescription = "select scenario" });
            scenarioList.AddRange(ServiceLocator.Get<ImportVM>().CurrentUserScenarioList.Where(c => c.PlanType == "USC" && c.UserName == App.LoginUserName).OrderBy(s => s.ScenarioName));
            OthersScenarioList = scenarioList;
            SelectedOtherScenario = OthersScenarioList[0];
        }

        #endregion

        #region Methods

        private void GetUserScenarioData()
        {
            string[] param = new string[] { StartDate.ToString("MM/dd/yyyy"), EndDate.ToString("MM/dd/yyyy"), App.LoginUserName };
            RelationalDataServiceClient queryClient = new RelationalDataServiceClient(FIFPServiceHostUtil.GetQueryBasicHttpBinding(), FIFPServiceHostUtil.GetQueryEndpointAddress());
            queryClient.QueryForDataAsync(FIFPConstants.DATASOURCE_ID, FIFPConstants.SCENARIO_CAPACITYDATA_QUERY_ID, param, "ScenarioData");
            queryClient.QueryForDataCompleted += new EventHandler<QueryForDataCompletedEventArgs>(ChartVM_QueryForGetScenarioDataCompleted);
        }

        private void LoadRadChart(RadChart radChart)
        {
            scenarioChart = radChart;
        }



        private void GetScenarioEffectiveCapacityFromDB()
        {
            ServiceLocator.Get<MainPageVM>().IsLoading = true;
            RelationalDataServiceClient queryClient = new RelationalDataServiceClient(FIFPServiceHostUtil.GetQueryBasicHttpBinding(), FIFPServiceHostUtil.GetQueryEndpointAddress());
            string[] param = new string[] { ServiceLocator.Get<ImportVM>().CurrentScenarioId.ToString(), StartDate.ToString("MM/dd/yyyy"), EndDate.ToString("MM/dd/yyyy") };
            queryClient.QueryForDataAsync(FIFPConstants.DATASOURCE_ID, FIFPConstants.SELECT_EFFECTIVE_CAPACITY_QUERY_ID, param, "CurrentScenarioData");
            queryClient.QueryForDataCompleted += new EventHandler<QueryForDataCompletedEventArgs>(ImportVM_QueryForCurrentScenarioDataCompleted);
        }

        void ImportVM_QueryForCurrentScenarioDataCompleted(object sender, QueryForDataCompletedEventArgs e)
        {
            ServiceLocator.Get<MainPageVM>().IsLoading = false;
            if (e.Result != null && e.Error == null && e.UserState.ToString() == "CurrentScenarioData")
            {
                try
                {
                    StringReader reader = new StringReader(e.Result.Any1.ToString());
                    XmlReader xmlR = XmlReader.Create(reader);

                    XDocument doc = XDocument.Load(xmlR);


                    if (doc != null)
                    {
                        List<ScenarioCapacity> currentScenarioCapacity = (from item in doc.Descendants("Query")
                                                                          select new ScenarioCapacity
                                                                          {
                                                                              ScenarioId = item.Element("ScenarioId") != null ? Convert.ToInt32(item.Element("ScenarioId").Value) : 0,
                                                                              ScenarioName = item.Element("ScenarioName") != null ? Convert.ToString(item.Element("ScenarioName").Value) : string.Empty,
                                                                              UserName = item.Element("UserName") != null ? Convert.ToString(item.Element("UserName").Value) : string.Empty,
                                                                              Date = item.Element("Date") != null ? Convert.ToDateTime(item.Element("Date").Value) : DateTime.MinValue,
                                                                              Capacity = item.Element("Capacity") != null ? Convert.ToDouble(item.Element("Capacity").Value) : 0,
                                                                              CapacityType = item.Element("CapacityType") != null ? Convert.ToString(item.Element("CapacityType").Value) : string.Empty,
                                                                          }).ToList<ScenarioCapacity>();

                        UpdateCurrentScenario(currentScenarioCapacity);

                    }
                }
                catch (Exception ex)
                { }
            }
            ServiceLocator.Get<MainPageVM>().IsLoading = false;
        }

        void ChartVM_QueryForGetScenarioDataCompleted(object sender, QueryForDataCompletedEventArgs e)
        {
            ServiceLocator.Get<MainPageVM>().IsLoading = false;
            if (e.Result != null && e.Error == null && e.UserState.ToString() == "ScenarioData")
            {
                try
                {
                    StringReader reader = new StringReader(e.Result.Any1.ToString());
                    XmlReader xmlR = XmlReader.Create(reader);

                    XDocument doc = XDocument.Load(xmlR);


                    if (doc != null)
                    {
                        UserScenarioCapacityDataList = (from item in doc.Descendants("Query")
                                                        select new ScenarioCapacity
                                                        {
                                                            ScenarioId = item.Element("ScenarioId") != null ? Convert.ToInt32(item.Element("ScenarioId").Value) : 0,
                                                            ScenarioName = item.Element("ScenarioName") != null ? Convert.ToString(item.Element("ScenarioName").Value) : string.Empty,
                                                            UserName = item.Element("UserName") != null ? Convert.ToString(item.Element("UserName").Value) : string.Empty,
                                                            Date = item.Element("Date") != null ? Convert.ToDateTime(item.Element("Date").Value) : DateTime.MinValue,
                                                            Capacity = item.Element("Capacity") != null ? Convert.ToDouble(item.Element("Capacity").Value) : 0,
                                                            CapacityType = item.Element("CapacityType") != null ? Convert.ToString(item.Element("CapacityType").Value) : string.Empty,
                                                        }).ToList<ScenarioCapacity>();

                        if (DataSeriesCapacityList != null && DataSeriesCapacityList.Count > 0)
                        {
                            List<string> keyList = DataSeriesCapacityList.Keys.ToList<string>();
                            foreach (string scenarioKey in keyList)
                            {
                                DataSeries series = DataSeriesCapacityList[scenarioKey];
                                if (series != null)
                                    scenarioChart.DefaultView.ChartArea.DataSeries.Remove(series);
                                /*if (scenarioKey == "EC")
                                {
                                    if (UserScenarioCapacityDataList != null && UserScenarioCapacityDataList.Count > 0)
                                    {
                                        List<ScenarioCapacity> capacityListByKey = new List<ScenarioCapacity>();
                                        capacityListByKey = UserScenarioCapacityDataList.Where(s => s.CapacityType == scenarioKey).ToList<ScenarioCapacity>();

                                        if (capacityListByKey != null && capacityListByKey.Count > 0)
                                        {
                                            DataSeries sm = new DataSeries();
                                            sm.LegendLabel = "EC Plan " + DateTime.Now.Year;
                                            sm.Definition = new LineSeriesDefinition();
                                            foreach (ScenarioCapacity capacity in capacityListByKey)
                                            {
                                                sm.Add(new DataPoint() { YValue = capacity.Capacity, XCategory = capacity.Date.ToString("yyyy/M") });
                                            }
                                            if (sm != null && sm.Count > 0)
                                            {
                                                DataSeriesCapacityList[scenarioKey] = sm;
                                                scenarioChart.DefaultView.ChartArea.DataSeries.Add(sm);
                                            }
                                        }
                                    }
                                }
                                else*/
                                {
                                    if (UserScenarioCapacityDataList != null && UserScenarioCapacityDataList.Count > 0)
                                    {
                                        List<ScenarioCapacity> capacityListByKey = new List<ScenarioCapacity>();
                                        if (scenarioKey == "RC" || scenarioKey == "MC")
                                            capacityListByKey = UserScenarioCapacityDataList.Where(s => s.CapacityType == scenarioKey).ToList<ScenarioCapacity>();
                                        else if (scenarioKey == "OC")
                                            capacityListByKey = UserScenarioCapacityDataList.Where(s => s.CapacityType == scenarioKey && s.ScenarioName == ServiceLocator.Get<ImportVM>().CurrentScenarioName).ToList<ScenarioCapacity>();
                                        else
                                            capacityListByKey = UserScenarioCapacityDataList.Where(s => s.ScenarioName == scenarioKey && s.CapacityType == "EC").ToList<ScenarioCapacity>();

                                        if (capacityListByKey != null && capacityListByKey.Count > 0)
                                        {
                                            DataSeries sm = new DataSeries();
                                            sm.LegendLabel = scenarioKey == "RC" ? "Reservoir Capacity" : scenarioKey == "MC" ? "100% Effiecient Capacity" : scenarioKey == "OC" ? "Available Oil" : scenarioKey + " - EC";
                                            sm.Definition = new LineSeriesDefinition();
                                            foreach (ScenarioCapacity capacity in capacityListByKey)
                                            {
                                                sm.Add(new DataPoint() { YValue = capacity.Capacity, XCategory = capacity.Date.ToString("yyyy/M") });
                                            }
                                            if (sm != null && sm.Count > 0)
                                            {
                                                DataSeriesCapacityList[scenarioKey] = sm;
                                                scenarioChart.DefaultView.ChartArea.DataSeries.Add(sm);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        //GetECPlanData();
                    }
                }
                catch (Exception ex)
                { }
            }
            //ServiceLocator.Get<MainPageVM>().IsLoading = false;
        }

        

        private void UpdateCurrentScenario(List<ScenarioCapacity> currentScenarioCapacityList)
        {
            string currentScenarioId = Convert.ToString(ServiceLocator.Get<ImportVM>().CurrentScenarioName);
            if (UserScenarioCapacityDataList != null)
            {
                //capacity data list update
                UserScenarioCapacityDataList.RemoveAll(s => s.ScenarioId == Convert.ToInt32(currentScenarioId));
                UserScenarioCapacityDataList.AddRange(currentScenarioCapacityList);
            }

            if (DataSeriesCapacityList.ContainsKey(currentScenarioId))
            {
                //sm.LegendLabel = (key.Key.CapacityType == "RC") ? "Reservoir Capacity" : "100% Effiecient Capacity";
                string legendLabel = string.Empty;
                ScenarioCapacity currentCapacity = currentScenarioCapacityList.Where(s => s.ScenarioId == Convert.ToInt32(currentScenarioId)).FirstOrDefault();
                DataSeries series = DataSeriesCapacityList[currentScenarioId];
                if (series != null)
                    scenarioChart.DefaultView.ChartArea.DataSeries.Remove(series);

                DataSeries sm = new DataSeries();
                sm.LegendLabel = legendLabel;
                sm.Definition = new LineSeriesDefinition();
                foreach (ScenarioCapacity capacity in currentScenarioCapacityList)
                {
                    sm.Add(new DataPoint() { YValue = capacity.Capacity, XCategory = capacity.Date.ToString("yyyy/M") });
                }
                if (sm != null && sm.Count > 0)
                {
                    DataSeriesCapacityList[currentScenarioId] = sm;
                    scenarioChart.DefaultView.ChartArea.DataSeries.Add(sm);
                }
            }
        }


        private void CapacityCheckedEvent(CheckBox chkCapacity)
        {
            string capacityType = Convert.ToString(chkCapacity.Tag);
            if (!string.IsNullOrEmpty(capacityType))
            {
                selectedCapacityType = capacityType;
                if (Convert.ToBoolean(chkCapacity.IsChecked))
                {
                    selectedCapacityTypes.Add(capacityType);
                    if (selectedCapacityType == "EC")
                        FilterECPlanCapacity();
                    else
                        FilterCapacity();
                }
                else
                {
                    if (!string.IsNullOrEmpty(selectedCapacityType) && DataSeriesCapacityList.ContainsKey(selectedCapacityType))
                    {
                        DataSeriesCapacityList.Remove(selectedCapacityType);
                        scenarioChart.DefaultView.ChartArea.DataSeries.RemoveAll();
                        foreach (string key in DataSeriesCapacityList.Keys)
                        {
                            if (DataSeriesCapacityList[key] != null && DataSeriesCapacityList[key].Count > 0)
                                scenarioChart.DefaultView.ChartArea.DataSeries.Add(DataSeriesCapacityList[key]);
                        }
                    }
                    selectedCapacityTypes.Remove(capacityType);
                }
            }
        }

        private void FilterScenario()//This belongs to user's scenario with capacity type = EC
        {

            var capacityList = from item in UserScenarioCapacityDataList
                               where (item.Date >= StartDate && item.Date <= EndDate) && selectedScenarioId == item.ScenarioName && item.CapacityType == "EC"
                               group item by new { item.ScenarioName, item.CapacityType } into g
                               select new { Key = g.Key, Values = g };

            if (capacityList != null && capacityList.Count() > 0)
            {
                foreach (var key in capacityList)
                {
                    DataSeries sm = new DataSeries();
                    sm.LegendLabel = key.Key.ScenarioName + " - " + key.Key.CapacityType;
                    sm.Definition = new LineSeriesDefinition();
                    foreach (ScenarioCapacity capacity in key.Values)
                    {
                        sm.Add(new DataPoint() { YValue = capacity.Capacity, XCategory = capacity.Date.ToString("yyyy/M") });
                    }
                    if (sm != null && sm.Count > 0)
                    {
                        if (!DataSeriesCapacityList.ContainsKey(selectedScenarioId))
                        {
                            DataSeriesCapacityList.Add(selectedScenarioId, sm);
                            scenarioChart.DefaultView.ChartArea.DataSeries.Add(sm);
                        }
                    }
                }
            }
            else
            {
                DataSeriesCapacityList.Add(selectedScenarioId, null);
                ShowPopup(selectedScenarioId, FIFPConstants.WARNINGMESSAGE_SCENARIO_USC);
            }
        }

        private void FilterCapacity()//This belongs to RC / MC scenario with capacity type = EC/MC
        {

            if (selectedCapacityTypes != null && selectedCapacityTypes.Count > 0)
            {
                var capacityList = from item in UserScenarioCapacityDataList
                                   where (item.Date >= StartDate && item.Date <= EndDate) && item.CapacityType == selectedCapacityType && (item.ScenarioId == ServiceLocator.Get<ImportVM>().CurrentScenarioId || item.ScenarioId == -1) //ScenarioId = -1 means we are getting RC and MC data
                                   group item by new { item.ScenarioName, item.CapacityType } into g
                                   select new { Key = g.Key, Values = g };

                if (capacityList != null && capacityList.Count() > 0)
                {
                    foreach (var key in capacityList)
                    {
                        DataSeries sm = new DataSeries();
                        sm.LegendLabel = (key.Key.CapacityType == "RC") ? "Reservoir Capacity" : (key.Key.CapacityType == "MC") ? "100% Effiecient Capacity" : "Available Oil";
                        sm.Definition = new LineSeriesDefinition();
                        foreach (ScenarioCapacity capacity in key.Values)
                        {
                            sm.Add(new DataPoint() { YValue = capacity.Capacity, XCategory = capacity.Date.ToString("yyyy/M") });
                        }
                        if (sm != null && sm.Count > 0)
                        {
                            if (!DataSeriesCapacityList.ContainsKey(selectedCapacityType))
                            {
                                DataSeriesCapacityList.Add(selectedCapacityType, sm);
                                scenarioChart.DefaultView.ChartArea.DataSeries.Add(sm);
                            }
                        }
                    }
                }
                else
                {
                    //if (selectedCapacityType == "EC" )
                    //{
                    //    ShowPopup(FIFPConstants.WARNINGTITLE_SCENARIO_EC, string.Format(FIFPConstants.WARNINGMESSAGE_SCENARIO_EC,DateTime.Now.Year));
                    //}
                    DataSeriesCapacityList.Add(selectedCapacityType, null);
                    if (selectedCapacityType == "RC")
                        ShowPopup(FIFPConstants.WARNINGTITLE_SCENARIO_RC, FIFPConstants.WARNINGMESSAGE_SCENARIO_RC);
                    else if (selectedCapacityType == "MC")
                        ShowPopup(FIFPConstants.WARNINGTITLE_SCENARIO_MC, FIFPConstants.WARNINGMESSAGE_SCENARIO_MC);
                    else if (selectedCapacityType == "OC")
                        ShowPopup(FIFPConstants.WARNINGTITLE_SCENARIO_OC, FIFPConstants.WARNINGMESSAGE_SCENARIO_USC);
                }
            }
            else
            {

            }
        }

        private void FilterECPlanCapacity() //This belongs to EC current year scenario with capacity type = EC current year
        {

            if (selectedCapacityTypes != null && selectedCapacityTypes.Count > 0)
            {
                var capacityList = from item in UserScenarioCapacityDataList
                                   where (item.Date >= StartDate && item.Date <= EndDate)
                                   group item by new { item.ScenarioName, item.CapacityType } into g
                                   select new { Key = g.Key, Values = g };

                if (capacityList != null && capacityList.Count() > 0)
                {
                    foreach (var key in capacityList)
                    {
                        DataSeries sm = new DataSeries();
                        sm.LegendLabel = "EC Plan " + DateTime.Now.Year;
                        sm.Definition = new LineSeriesDefinition();
                        foreach (ScenarioCapacity capacity in key.Values)
                        {
                            sm.Add(new DataPoint() { YValue = capacity.Capacity, XCategory = capacity.Date.ToString("yyyy/M") });
                        }
                        if (sm != null && sm.Count > 0)
                        {
                            if (!DataSeriesCapacityList.ContainsKey(selectedCapacityType))
                            {
                                DataSeriesCapacityList.Add(selectedCapacityType, sm);
                                scenarioChart.DefaultView.ChartArea.DataSeries.Add(sm);
                            }
                        }
                    }
                }
                else
                {
                    DataSeriesCapacityList.Add(selectedCapacityType, null);
                    if (selectedCapacityType == "EC")
                    {
                        ShowPopup(FIFPConstants.WARNINGTITLE_SCENARIO_EC, string.Format(FIFPConstants.WARNINGMESSAGE_SCENARIO_EC, DateTime.Now.Year));
                    }
                }
            }
        }

        private void ShowPopup(string title, string message)
        {
            Warning warningWindow = new Warning();
            warningWindow.CancelButton.Visibility = Visibility.Collapsed;
            warningWindow.Title = string.Format(title);
            warningWindow.lblMessage.Text = string.Format(message);
            warningWindow.lblMessage.Visibility = Visibility.Visible;
            warningWindow.Show();
            warningWindow.OKButton.Click += (o, e1) =>
            {
                warningWindow.lblMessage.Visibility = Visibility.Collapsed;
            };
        }


        private void ScenarioCheckedEvent(CheckBox chkScenario)
        {
            string scenarioId = Convert.ToString(chkScenario.Tag);
            if (!string.IsNullOrEmpty(scenarioId))
            {
                selectedScenarioId = scenarioId;
                if (Convert.ToBoolean(chkScenario.IsChecked))
                {
                    selectedScenarioIds.Add(scenarioId);
                    FilterScenario();
                }
                else
                {
                    if (!string.IsNullOrEmpty(selectedScenarioId) && DataSeriesCapacityList.ContainsKey(selectedScenarioId))
                    {
                        DataSeriesCapacityList.Remove(selectedScenarioId);
                        scenarioChart.DefaultView.ChartArea.DataSeries.RemoveAll();
                        foreach (string key in DataSeriesCapacityList.Keys)
                        {
                            if (DataSeriesCapacityList[key] != null && DataSeriesCapacityList[key].Count > 0)
                                scenarioChart.DefaultView.ChartArea.DataSeries.Add(DataSeriesCapacityList[key]);
                        }
                    }
                    selectedScenarioIds.Remove(scenarioId);
                }
            }
        }

        #region DoValidation
        private bool DoDateValidation()
        {
            bool bRet = true;

            if (StartDate > EndDate)
            {
                bRet = false;
                NotifyPropertyChanged(() => StartDate);
            }
            else if (EndDate < StartDate)
            {
                bRet = false;
                NotifyPropertyChanged(() => EndDate);
            }
            else
            {
                NotifyPropertyChanged(() => StartDate);
                NotifyPropertyChanged(() => EndDate);
            }

            return bRet;
        }
        #endregion

        #region StartDate_SelectedDateChanged
        private void StartDate_SelectedDateChanged(DatePicker datePicker)
        {
            if (FromDate.SelectedDate != null)
            {
                if (EndDate != null)
                {
                    //if (EndDate < StartDate)
                    //    EndDate = null;
                }
                this.ToDate.BlackoutDates.Clear();
                this.ToDate.BlackoutDates.Add(new CalendarDateRange(new DateTime(), ((DateTime)this.FromDate.SelectedDate).AddDays(-1)));
            }
        }
        #endregion
        DatePicker FromDate = new DatePicker();
        private void LoadStartDate(DatePicker startDatePicker)
        {
            FromDate = startDatePicker;
            FromDate.BlackoutDates.Add((new CalendarDateRange(new DateTime(), Convert.ToDateTime(StartDate).AddDays(-1))));
        }
        DatePicker ToDate = new DatePicker();
        private void LoadEndDate(DatePicker endDatePicker)
        {
            ToDate = endDatePicker;
            ToDate.BlackoutDates.Add((new CalendarDateRange(new DateTime(), Convert.ToDateTime(StartDate).AddDays(-1))));
        }

        #region Validation
        protected void NotifyPropertyChanged(Expression<Func<object>> propertyExpression)
        {
            if (propertyExpression == null)
                throw new ArgumentNullException(FIFPConstants.propertyExpression);

            var propertyName = GetPropertyName(propertyExpression);
            OnPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            Validate(propertyName);
            OnNotifyPropertyChanged();
        }

        protected virtual void OnNotifyPropertyChanged() { }

        private string GetPropertyName(Expression<Func<object>> propertyExpression)
        {
            var unaryExpression = propertyExpression.Body as UnaryExpression;
            var memberExpression = unaryExpression == null ? (MemberExpression)propertyExpression.Body : (MemberExpression)unaryExpression.Operand;

            var propertyName = memberExpression.Member.Name;

            return propertyName;
        }


        private void NotifyErrorsChanged(string propertyName)
        {
            ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
        }

        protected void Validate(string propertyName)
        {
            var value = GetPropertyValue(propertyName);
            RemoveErrorsForProperty(propertyName);
            Validator.TryValidateProperty(value, new ValidationContext(this, null, null) { MemberName = propertyName }, _validationResults);
            NotifyErrorsChanged(propertyName);
        }

        protected void Validate()
        {
            _validationResults.Clear();
            Validator.TryValidateObject(this, new ValidationContext(this, null, null), _validationResults, true);

            foreach (var result in _validationResults)
                NotifyErrorsChanged(result.MemberNames.First());

        }

        private object GetPropertyValue(string propertyName)
        {
            var type = this.GetType();

            var propertyInfo = type.GetProperty(propertyName);

            if (propertyInfo == null)
            {
                throw new ArgumentException(string.Format(FIFPConstants.Couldntfindanyproperty, propertyName, type));
            }

            return propertyInfo.GetValue(this, null);
        }

        private void RemoveErrorsForProperty(string propertyName)
        {
            var validationResults = _validationResults.Where(result => result.MemberNames.Contains(propertyName)).ToList();

            foreach (var result in validationResults)
                _validationResults.Remove(result);
        }

        public IEnumerable GetErrors(string propertyName)
        {
            return _validationResults.Where(result => result.MemberNames.Contains(propertyName));
        }

        public bool HasErrors
        {
            get { return _validationResults.Any(); }
        }

        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
        //public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #endregion
    }
}